#include "hik_camera.h"
// #include "LinuxPlayM4.h"
#include <string>
#include <algorithm>
#include <vector>
#include <unistd.h>
#include <cstring>

bool HikCamera::setIp(std::string _ip){
    ip = _ip;
    return true;
}

bool HikCamera::setPort(int _port){
    port = _port;
    return true;
}

bool HikCamera::setPWD(std::string _pwd){
    pwd = _pwd;
    return true;
}

bool HikCamera::setUser(std::string _user){
    user = _user;
    return true;
}

HikCamera::HikCamera(){
port=8000;
pwd="scdx1234";
user="admin";
}

HikCamera::HikCamera(std::string ip_, int port_, std::string pwd_, std::string user_):ip(ip_),port(port_),pwd(pwd_),user(user_),lUserID(-1){
}

bool HikCamera::getInfo(){
    std::cout<<ip<<":"<<port<<" "<<user<<" "<<pwd<<std::endl;
}

bool HikCamera::start(){

    initOK=NET_DVR_Init();
    initOK&=NET_DVR_SetConnectTime(2000, 1);
    initOK&=NET_DVR_SetReconnect(10000, true);

    struLoginInfo.bUseAsynLogin = false;//bUseAsynLogin为0时登录为同步模式  为1时为异步登陆
    struLoginInfo.wPort = port;
    strcpy(struLoginInfo.sDeviceAddress, ip.c_str());
    strcpy(struLoginInfo.sUserName, user.c_str());
    strcpy(struLoginInfo.sPassword, pwd.c_str());
    struLoginInfo.wPort=port;
    lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);
    if (!check()){
        return false;
    }

    lpInBuffer.dwSize = sizeof(lpInBuffer);
    lpInBuffer.struStreamInfo.dwSize = sizeof(lpInBuffer.struStreamInfo);
    lpInBuffer.struStreamInfo.dwChannel = 1;
    lpInBuffer.dwStreamType = 0;
    lpInParamBuffer.dwSize = sizeof(lpInParamBuffer);
}

bool HikCamera::check(){
    if(lUserID < 0){
        std::cout << "NET_DVR_Login_V40 failed. " << NET_DVR_GetLastError() << std::endl;
        return false;
    }
    return true;
}

bool HikCamera::capture(){
    NET_DVR_JPEGPARA struJPEGPara{0};
    struJPEGPara.wPicQuality = 2;
    struJPEGPara.wPicSize = 0;
    int iRet;

    iRet = NET_DVR_CaptureJPEGPicture(lUserID, struDeviceInfoV40.struDeviceV30.byStartChan, &struJPEGPara,
    "/home/admin508/wjk_test/HIK/CH-HCNetSDKV6.1.9.48_build20230410_linux64/HIK_TEST/capture/cap.jpeg");

    if(!iRet){
        std::cout << "NET_DVR_CaptureJPEGPicture failed. " << NET_DVR_GetLastError() << std::endl;
        return false;
    }
    return true;
}



HikCamera::~HikCamera(){
    std::cout << "Destroy HikvisionVideoReader" << std::endl;
    NET_DVR_StopRealPlay(handle);
    NET_DVR_Logout_V30(lUserID);
    NET_DVR_Cleanup();

}

bool HikCamera::getCFG(){
    bool get = NET_DVR_GetDeviceConfig(lUserID,NET_DVR_GET_MULTI_STREAM_COMPRESSIONCFG,1,&lpInBuffer,lpInBuffer.dwSize,&status,&lpInParamBuffer,lpInParamBuffer.dwSize);
    if(get){
        std::cout<< "GET ok\n";
        return true;
    }else{
        std::cout<<"GET error: "<<NET_DVR_GetLastError()<<std::endl;
        return false;
    }
}

bool HikCamera::setParams(std::string k, int v){
    std::unordered_map<std::string,int>::iterator it = outParamsMap.find(k);
    if(outParamsMap.end() == it){
        std::cout<<"key not exist\n";
    }else{
        outParamsMap[k] = v;
    }
}

bool HikCamera::setCFG(){
    getCFG();

    lpInParamBuffer.dwStreamType = outParamsMap["dwStreamType"]; //0-主码流
    lpInParamBuffer.struStreamPara.byStreamType = outParamsMap["byStreamType"]; //0视频流，1复合流
    lpInParamBuffer.struStreamPara.byResolution = outParamsMap["byResolution"]; // 19=1280*720, 27=1920*1080 70=2560*1440 186=3200*1800 64=3840*2160 0xff使用当前码率分辨率
    lpInParamBuffer.dwResolution = lpInParamBuffer.struStreamPara.byResolution;
    lpInParamBuffer.struStreamPara.byBitrateType = outParamsMap["byBitrateType"]; //0变码率，1定码率
    lpInParamBuffer.struStreamPara.dwVideoBitrate = outParamsMap["dwVideoBitrate"]; //21=1536k、1792、2048、3072、4096、8192、... 0xfffffffe=自动
    lpInParamBuffer.struStreamPara.dwVideoFrameRate = outParamsMap["dwVideoFrameRate"]; //13=20 17=25, 0xfffffffe=自动
    lpInParamBuffer.struStreamPara.wIntervalFrameI = outParamsMap["wIntervalFrameI"]; //值, 0xfffe=自动
    lpInParamBuffer.struStreamPara.byVideoEncType = outParamsMap["byVideoEncType"]; //10-标准265 0=私有264 1=标准264 0xfe=自动
    lpInParamBuffer.struStreamPara.byStreamSmooth = outParamsMap["byStreamSmooth"]; //值，平滑系数
    

    bool ok = NET_DVR_SetDeviceConfig(lUserID,NET_DVR_SET_MULTI_STREAM_COMPRESSIONCFG,1,&lpInBuffer,lpInBuffer.dwSize,&status,&lpInParamBuffer,lpInParamBuffer.dwSize);
    if(ok){
        std::cout<< "SET ok\n";
        return true;
    }else{
        std::cout<<"SET error: "<<NET_DVR_GetLastError()<<std::endl;
        return false;
    }
}